package com.artfii.fluentsql.core.tools;

import org.yaml.snakeyaml.Yaml;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Func :加载属性文件
 *
 * @author: leeton on 2019/3/27.
 */
public class PropUtil {
    public static Properties load(String file) {
        Properties properties = new Properties();
        InputStream reader = null;
        try {
            reader = loadFileStream(file);
            properties.load(reader);
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (reader != null) {
                reader = null;
            }
        }
        return properties;
    }

    /**
     * 读取Properties文件设置值到配置类
     *
     * @param propertiesFile Properties文件
     * @param targetClz      配置类
     * @return
     */
    public static <T> T loadAndSetToClass(String propertiesFile, Class<T> targetClz) {
        Properties props = load(propertiesFile);
        T target = newInstance(targetClz);
        if (!props.isEmpty()) {
            HashMap<String, Field> fieldMap = new HashMap(props.size());
            Field[] fields = targetClz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                fieldMap.put(field.getName(), field);
            }
            for (String pKey : props.stringPropertyNames()) {
                String v = props.getProperty(pKey).trim().intern();
                if (null != fieldMap.get(pKey)) {
                    setField(target, fieldMap.get(pKey), v);
                }
            }
            fieldMap.clear();
        }
        return target;
    }

    /**
     * 读取YML设置值到配置类
     *
     * @param ymlFile   YML 配置文件
     * @param targetClz 配置类
     * @return
     */
    public static <T> T loadYmlToClass(String ymlFile, Class<T> targetClz) {
        Yaml yaml = new Yaml();
        T target = yaml.loadAs(loadFileStream(ymlFile), targetClz);
        return target;
    }

    public static Map<String, Object> loadYmlToMap(String ymlFile) {
        return new Yaml().loadAs(loadFileStream(ymlFile), HashMap.class);
    }

    public static void printAll(Properties props) {
        Enumeration en = props.propertyNames();
        while (en.hasMoreElements()) {
            String key = (String) en.nextElement();
            String value = props.getProperty(key);
            System.out.println(key + " : " + value);
        }
    }

    /**
     * 按文件路径取得文件流
     *
     * @param fileAndPath 要填写相对class路径
     * @return
     */
    private static InputStream loadFileStream(String fileAndPath) {
        //fileAndPath要填写相对路径
        InputStream is = null;
        is = ClassLoader.getSystemResourceAsStream(fileAndPath);
        if (null == is) {
            is = PropUtil.class.getClassLoader().getResourceAsStream(fileAndPath);
            if (null == is) {
                is = PropUtil.class.getClass().getResourceAsStream(fileAndPath);
                if (null == is) {
                    is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileAndPath);

                }
            }
        }
        return is;
    }

    private static void setField(Object clz, Field field, String v) {
        try {
            if (field.getType() == String.class) {
                field.set(clz, v);
            }
            if (field.getType() == Integer.class || field.getType() == int.class) {
                field.set(clz, Integer.valueOf(v));
            }
            if (field.getType() == Boolean.class || field.getType() == boolean.class) {
                field.set(clz, Boolean.valueOf(v));
            }
            if (field.getType() == Long.class || field.getType() == long.class) {
                field.set(clz, Long.valueOf(v));
            }

        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    private static <T> T newInstance(Class<T> tClass) {
        try {
            return tClass.newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getDefEnv() {
        return getEnv("dev");
    }

    public static String getDefEnv(String defEnv) {

        String env = getEnv("spring.profiles.active");
        if (null == env) {
            env = getEnv("env");
        }
        return null == env ? defEnv : env;
    }

    private static String getEnv(String envKey) {
        String env = System.getenv(envKey);
        if (env == null) {
            env = System.getProperty(envKey);
        }
        return env;

    }


    public static void main(String[] args) {
        PropUtil.printAll(PropUtil.load("db.properties"));
    }


}
